package com.jiulong.controller;


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.jiulong.common.utils.HttpUtil;
import com.jiulong.common.utils.PayCommonUtil;
import com.jiulong.common.utils.PayConfigUtil;
import com.jiulong.common.utils.XMLUtil;
import com.opensymphony.xwork2.ActionContext;


public class weixin_pay {

    public static void main(String[] args) throws Exception {
        String total_fee = "1";
        String out_trade_no = "xiakaitest12345";

        weixin_payH5(total_fee, out_trade_no);

    }

    /**
     * 微信支付统一下单接口
     *
     * @param openid
     * @param out_trade_no
     * @throws Exception
     */
    public static String weixin_pay(String openid, String amount1, String out_trade_no) throws Exception {
        // 账号信息
        //String out_trade_no = out_trade_no;
        String appid = PayConfigUtil.getAppid();  // appid
        String total_fee = amount1;
        // 商业号
        String mch_id = PayConfigUtil.getMchid();
        // key
        String key = PayConfigUtil.getKey();
        String openid1 = openid;
        System.out.println("openid用来生成预支付订单！" + openid1);
        String currTime = PayCommonUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        //随机字符串
        String nonce_str = strTime + strRandom;
        System.out.println(nonce_str);
        // 商品名称
        String body = "久龙精品酒店欢迎您的入住！";
        // 获取发起电脑 ip
        String spbill_create_ip = PayConfigUtil.getIP();
        // 回调接口 
        String notify_url = PayConfigUtil.NOTIFY_URL;
        String trade_type = "JSAPI";
        String time_start = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(Calendar.DATE, 1);
        String time_expire = new SimpleDateFormat("yyyyMMddHHmmss").format(ca.getTime());
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);//T
        packageParams.put("mch_id", mch_id);//T
        packageParams.put("nonce_str", nonce_str);//T
        packageParams.put("out_trade_no", out_trade_no);//T
        packageParams.put("total_fee", total_fee);//T
        packageParams.put("spbill_create_ip", "127.0.0.1");//T
        packageParams.put("notify_url", notify_url);//T
        packageParams.put("trade_type", trade_type);
        packageParams.put("time_start", time_start);
        packageParams.put("time_expire", time_expire);
        packageParams.put("openid", openid1);
        packageParams.put("sign_type", "MD5");//T
        packageParams.put("body", body);//T
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
        packageParams.put("sign", sign);//T
        System.out.println(sign);
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        System.out.println("请求xml：：：：" + requestXML);
        String resXml = HttpUtil.postData(PayConfigUtil.PAY_API, requestXML);
        System.out.println("返回xml：：：：" + resXml);
        Map map = XMLUtil.doXMLParse(resXml);
        String prepay_id = (String) map.get("prepay_id");
        System.out.println(prepay_id);

        SortedMap<Object, Object> params = new TreeMap<Object, Object>();
        params.put("appId", PayConfigUtil.getAppid());
        params.put("timeStamp", Long.toString(new Date().getTime()));
        params.put("nonceStr", PayCommonUtil.buildRandom(10) + "");
        params.put("package", "prepay_id=" + map.get("prepay_id"));
        params.put("signType", "MD5");
        String paySign = PayCommonUtil.createSign("UTF-8", params, key);
        // params.put("packageValue", "prepay_id="+map.get("prepay_id"));    //这里用packageValue是预防package是关键字在js获取值出错
        params.put("paySign", paySign);                                                          //paySign的生成规则和Sign的生成规则一致
        // params.put("sendUrl", "www.baidu.com");                               //付款成功后跳转的页面
        String json = JSONObject.toJSONString(params);
        System.out.println(json);
        return json;
    }


    /**
     * 微信支付扫码支付接口
     *
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    public static String weixin_pay(String total_fee, String out_trade_no) throws Exception {
        // 账号信息
        String appid = PayConfigUtil.getAppid();  // appid
        // 商业号
        String mch_id = PayConfigUtil.getMchid();
        // key
        String key = PayConfigUtil.getKey();

        String currTime = PayCommonUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        //随机字符串
        String nonce_str = strTime + strRandom;
        // 价格   注意：价格的单位是分
        //String order_price = "1"; 
        // 商品名称
        String body = "久龙精品酒店欢迎您的入住！";
        //查询订单数据表获取订单信息
        // 获取发起电脑 ip
        String spbill_create_ip = PayConfigUtil.getIP();
        // 回调接口 
        String notify_url = PayConfigUtil.NOTIFY_URL;
        String trade_type = "NATIVE";
        String time_start = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(Calendar.DATE, 1);
        String time_expire = new SimpleDateFormat("yyyyMMddHHmmss").format(ca.getTime());
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", "127.0.0.1");
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        packageParams.put("time_start", time_start);
        packageParams.put("time_expire", time_expire);
        packageParams.put("body", body);
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
        packageParams.put("sign", sign);
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        System.out.println("请求xml：：：：" + requestXML);

        String resXml = HttpUtil.postData(PayConfigUtil.PAY_API, requestXML);
        System.out.println("返回xml：：：：" + resXml);

        Map map = XMLUtil.doXMLParse(resXml);


        String prepay_id = (String) map.get("prepay_id");
        String urlCode = (String) map.get("code_url");
        System.out.println("打印调用统一下单接口生成二维码url:::::" + urlCode + "prepay_id" + prepay_id);

        return urlCode;
    }


    /**
     * 微信H5支付支付接口
     *
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    public static String weixin_payH5(String total_fee, String out_trade_no) throws Exception {
        // 账号信息
        String appid = PayConfigUtil.getAppid();  // appid
        // 商业号
        String mch_id = PayConfigUtil.getMchid();
        // key
        String key = PayConfigUtil.getKey();

        String currTime = PayCommonUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        //随机字符串
        String nonce_str = strTime + strRandom;
        // 价格   注意：价格的单位是分
        //String order_price = "1"; 
        // 商品名称
        String body = "久龙精品酒店欢迎您的入住！";
        //查询订单数据表获取订单信息
        // 获取发起电脑 ip
        String spbill_create_ip = PayConfigUtil.getIP();
        // 回调接口 
        String notify_url = PayConfigUtil.NOTIFY_URL;
        String trade_type = "MWEB";
        String time_start = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(Calendar.DATE, 1);
        // {\"h5_info\": {\"type\":\"IOS/Android\",\"app_name\": \"久龙精品酒店\",\"package_name\":\"com.jiulong.common.utils\"}}
        String scene_info1 = "{\"h5_info\": {\"type\":\"IOS/Android\",\"app_name\": \"久龙精品酒店\",";
        String scene_info2 = ":\"com.jiulong.common.utils\"}}";
        String scene_info3 = "\"package_name\"";
        String scene_info = scene_info1 + scene_info2 + scene_info3;
        String time_expire = new SimpleDateFormat("yyyyMMddHHmmss").format(ca.getTime());
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("total_fee", total_fee);
        packageParams.put("spbill_create_ip", "127.0.0.1");
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        packageParams.put("time_start", time_start);
        packageParams.put("time_expire", time_expire);
        packageParams.put("body", body);
        packageParams.put("scene_info", scene_info);
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
        packageParams.put("sign", sign);
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        System.out.println("请求xml：：：：" + requestXML);

        String resXml = HttpUtil.postData(PayConfigUtil.PAY_API, requestXML);
        System.out.println("返回xml：：：：" + resXml);

        Map map = XMLUtil.doXMLParse(resXml);
        String prepay_id = (String) map.get("prepay_id");

        return null;
    }


    /**
     * 支付成功后，微信服务端开始回调方法
     *
     * @param request
     * @param response
     * @throws Exception
     */

    public void weixinNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("支付回调方法开始！");
        HashMap<String, Object> map = new HashMap<String, Object>();
        //wxPayService.weixin_notify(request, response);
        System.out.println("支付回调方法结束！");
    }

    /**
     * 微信支付回调方法
     *
     * @param request
     * @param response
     * @throws Exception
     */
    public void weixin_notify(HttpServletRequest request, HttpServletResponse response) throws Exception {

        //读取参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();

        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());

        //过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);

            String v = "";
            if (null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 账号信息
        String key = PayConfigUtil.getKey(); // key
        String out_trade_no = (String) packageParams.get("out_trade_no");
        //logger.info(packageParams);
        //判断签名是否正确
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
            //------------------------------
            //处理业务开始
            //------------------------------
            String resXml = "";
            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
                // 这里是支付成功

                String mch_id = (String) packageParams.get("mch_id");
                String openid = (String) packageParams.get("openid");
                String is_subscribe = (String) packageParams.get("is_subscribe");

                String bank_type = (String) packageParams.get("bank_type");
                String total_fee = (String) packageParams.get("total_fee");
                String transaction_id = (String) packageParams.get("transaction_id");

                System.out.println("mch_id:" + mch_id);
                System.out.println("openid:" + openid);
                System.out.println("is_subscribe:" + is_subscribe);
                System.out.println("out_trade_no:" + out_trade_no);
                System.out.println("total_fee:" + total_fee);
                System.out.println("bank_type:" + bank_type);
                System.out.println("transaction_id:" + transaction_id);

                //成功回调后需要处理预生成订单的状态和一些支付信息
                //查询数据库中订单，首先判定订单中金额与返回的金额是否相等，不等金额被纂改
                //判定订单是否已经被支付，不可重复支付
                //正常处理相关业务逻辑

            } else {
                System.out.println("支付失败,错误信息：" + packageParams.get("err_code") +
                        "-----订单号：：：" + out_trade_no + "*******支付失败时间：：：："
                        + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

                String err_code = (String) packageParams.get("err_code");

                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";

            }
            //------------------------------
            //处理业务完毕
            //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } else {
            System.out.println("通知签名验证失败---时间::::" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        }

    }
}
